using DocumentCreationSystem.Models;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.RegularExpressions;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 增强的工具调用解析器
    /// </summary>
    public interface IEnhancedToolCallParser
    {
        /// <summary>
        /// 解析文本中的工具调用
        /// </summary>
        List<EnhancedToolCall> ParseToolCalls(string text);

        /// <summary>
        /// 验证工具调用格式
        /// </summary>
        ToolCallValidationResult ValidateToolCall(EnhancedToolCall toolCall);

        /// <summary>
        /// 格式化工具调用结果
        /// </summary>
        string FormatToolCallResult(EnhancedToolCall toolCall, object result);

        /// <summary>
        /// 支持的工具调用格式
        /// </summary>
        List<ToolCallFormat> SupportedFormats { get; }
    }

    /// <summary>
    /// 增强的工具调用解析器实现
    /// </summary>
    public class EnhancedToolCallParser : IEnhancedToolCallParser
    {
        private readonly ILogger<EnhancedToolCallParser> _logger;

        public List<ToolCallFormat> SupportedFormats { get; } = new()
        {
            ToolCallFormat.NativeFunction,
            ToolCallFormat.TextBased,
            ToolCallFormat.ActionBased,
            ToolCallFormat.JsonBased,
            ToolCallFormat.MarkdownBased,
            ToolCallFormat.XMLBased
        };

        // 各种格式的正则表达式
        private static readonly Dictionary<ToolCallFormat, Regex> FormatPatterns = new()
        {
            [ToolCallFormat.TextBased] = new Regex(@"\[TOOL:(\w+)\](.*?)\[/TOOL\]", RegexOptions.Singleline | RegexOptions.IgnoreCase),
            [ToolCallFormat.ActionBased] = new Regex(@"\[ACTION:([^\]]+)\]", RegexOptions.IgnoreCase),
            [ToolCallFormat.JsonBased] = new Regex(@"```json\s*(\{.*?\})\s*```", RegexOptions.Singleline | RegexOptions.IgnoreCase),
            [ToolCallFormat.MarkdownBased] = new Regex(@"```(\w+)\s*(.*?)\s*```", RegexOptions.Singleline | RegexOptions.IgnoreCase),
            [ToolCallFormat.XMLBased] = new Regex(@"<tool\s+name=[""'](\w+)[""'](?:\s+args=[""']([^""']*)[""'])?\s*/?>", RegexOptions.IgnoreCase)
        };

        public EnhancedToolCallParser(ILogger<EnhancedToolCallParser> logger)
        {
            _logger = logger;
        }

        public List<EnhancedToolCall> ParseToolCalls(string text)
        {
            var toolCalls = new List<EnhancedToolCall>();

            try
            {
                // 解析各种格式的工具调用
                foreach (var format in SupportedFormats)
                {
                    var calls = ParseFormat(text, format);
                    toolCalls.AddRange(calls);
                }

                // 按出现顺序排序
                toolCalls = toolCalls.OrderBy(tc => tc.Position).ToList();

                _logger.LogInformation($"解析到 {toolCalls.Count} 个工具调用");
                return toolCalls;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "解析工具调用失败");
                return new List<EnhancedToolCall>();
            }
        }

        private List<EnhancedToolCall> ParseFormat(string text, ToolCallFormat format)
        {
            var toolCalls = new List<EnhancedToolCall>();

            switch (format)
            {
                case ToolCallFormat.TextBased:
                    toolCalls.AddRange(ParseTextBasedCalls(text));
                    break;
                case ToolCallFormat.ActionBased:
                    toolCalls.AddRange(ParseActionBasedCalls(text));
                    break;
                case ToolCallFormat.JsonBased:
                    toolCalls.AddRange(ParseJsonBasedCalls(text));
                    break;
                case ToolCallFormat.MarkdownBased:
                    toolCalls.AddRange(ParseMarkdownBasedCalls(text));
                    break;
                case ToolCallFormat.XMLBased:
                    toolCalls.AddRange(ParseXMLBasedCalls(text));
                    break;
                case ToolCallFormat.NativeFunction:
                    toolCalls.AddRange(ParseNativeFunctionCalls(text));
                    break;
            }

            return toolCalls;
        }

        private List<EnhancedToolCall> ParseTextBasedCalls(string text)
        {
            var toolCalls = new List<EnhancedToolCall>();
            var pattern = FormatPatterns[ToolCallFormat.TextBased];
            var matches = pattern.Matches(text);

            foreach (Match match in matches)
            {
                var toolName = match.Groups[1].Value;
                var parametersText = match.Groups[2].Value.Trim();
                var parameters = ParseParameters(parametersText);

                toolCalls.Add(new EnhancedToolCall
                {
                    ToolName = toolName,
                    Parameters = parameters,
                    Format = ToolCallFormat.TextBased,
                    OriginalText = match.Value,
                    Position = match.Index,
                    Confidence = 0.9f
                });
            }

            return toolCalls;
        }

        private List<EnhancedToolCall> ParseActionBasedCalls(string text)
        {
            var toolCalls = new List<EnhancedToolCall>();
            var pattern = FormatPatterns[ToolCallFormat.ActionBased];
            var matches = pattern.Matches(text);

            foreach (Match match in matches)
            {
                var actionDescription = match.Groups[1].Value;
                var inferredTool = InferToolFromAction(actionDescription);

                if (inferredTool != null)
                {
                    toolCalls.Add(inferredTool);
                    inferredTool.OriginalText = match.Value;
                    inferredTool.Position = match.Index;
                    inferredTool.Format = ToolCallFormat.ActionBased;
                }
            }

            return toolCalls;
        }

        private List<EnhancedToolCall> ParseJsonBasedCalls(string text)
        {
            var toolCalls = new List<EnhancedToolCall>();
            var pattern = FormatPatterns[ToolCallFormat.JsonBased];
            var matches = pattern.Matches(text);

            foreach (Match match in matches)
            {
                try
                {
                    var jsonText = match.Groups[1].Value;
                    var jsonDoc = JsonDocument.Parse(jsonText);
                    var root = jsonDoc.RootElement;

                    if (root.TryGetProperty("tool", out var toolElement) && 
                        root.TryGetProperty("parameters", out var paramsElement))
                    {
                        var toolName = toolElement.GetString() ?? "";
                        var parameters = JsonSerializer.Deserialize<Dictionary<string, object>>(paramsElement.GetRawText()) ?? new();

                        toolCalls.Add(new EnhancedToolCall
                        {
                            ToolName = toolName,
                            Parameters = parameters,
                            Format = ToolCallFormat.JsonBased,
                            OriginalText = match.Value,
                            Position = match.Index,
                            Confidence = 0.95f
                        });
                    }
                }
                catch (JsonException ex)
                {
                    _logger.LogWarning(ex, "解析JSON工具调用失败");
                }
            }

            return toolCalls;
        }

        private List<EnhancedToolCall> ParseMarkdownBasedCalls(string text)
        {
            var toolCalls = new List<EnhancedToolCall>();
            var pattern = FormatPatterns[ToolCallFormat.MarkdownBased];
            var matches = pattern.Matches(text);

            foreach (Match match in matches)
            {
                var language = match.Groups[1].Value.ToLower();
                var content = match.Groups[2].Value.Trim();

                // 检查是否是工具调用相关的代码块
                if (language == "tool" || language == "function" || language == "call")
                {
                    var toolCall = ParseToolCallFromContent(content);
                    if (toolCall != null)
                    {
                        toolCall.Format = ToolCallFormat.MarkdownBased;
                        toolCall.OriginalText = match.Value;
                        toolCall.Position = match.Index;
                        toolCalls.Add(toolCall);
                    }
                }
            }

            return toolCalls;
        }

        private List<EnhancedToolCall> ParseXMLBasedCalls(string text)
        {
            var toolCalls = new List<EnhancedToolCall>();
            var pattern = FormatPatterns[ToolCallFormat.XMLBased];
            var matches = pattern.Matches(text);

            foreach (Match match in matches)
            {
                var toolName = match.Groups[1].Value;
                var argsText = match.Groups[2].Value;
                var parameters = ParseParameters(argsText);

                toolCalls.Add(new EnhancedToolCall
                {
                    ToolName = toolName,
                    Parameters = parameters,
                    Format = ToolCallFormat.XMLBased,
                    OriginalText = match.Value,
                    Position = match.Index,
                    Confidence = 0.9f
                });
            }

            return toolCalls;
        }

        private List<EnhancedToolCall> ParseNativeFunctionCalls(string text)
        {
            var toolCalls = new List<EnhancedToolCall>();

            // 解析类似函数调用的格式: function_name(param1="value1", param2="value2")
            var functionPattern = new Regex(@"(\w+)\s*\(\s*(.*?)\s*\)", RegexOptions.IgnoreCase);
            var matches = functionPattern.Matches(text);

            foreach (Match match in matches)
            {
                var functionName = match.Groups[1].Value;
                var parametersText = match.Groups[2].Value;

                // 检查是否是已知的工具函数
                if (IsKnownToolFunction(functionName))
                {
                    var parameters = ParseFunctionParameters(parametersText);

                    toolCalls.Add(new EnhancedToolCall
                    {
                        ToolName = functionName,
                        Parameters = parameters,
                        Format = ToolCallFormat.NativeFunction,
                        OriginalText = match.Value,
                        Position = match.Index,
                        Confidence = 0.85f
                    });
                }
            }

            return toolCalls;
        }

        private Dictionary<string, object> ParseParameters(string parametersText)
        {
            var parameters = new Dictionary<string, object>();

            if (string.IsNullOrWhiteSpace(parametersText))
                return parameters;

            try
            {
                // 尝试解析为JSON
                if (parametersText.TrimStart().StartsWith("{"))
                {
                    return JsonSerializer.Deserialize<Dictionary<string, object>>(parametersText) ?? new();
                }

                // 解析键值对格式: key1=value1, key2=value2
                var kvPattern = new Regex(@"(\w+)\s*=\s*([""']?)([^,""']*)\2", RegexOptions.IgnoreCase);
                var matches = kvPattern.Matches(parametersText);

                foreach (Match match in matches)
                {
                    var key = match.Groups[1].Value;
                    var value = match.Groups[3].Value;
                    parameters[key] = value;
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "解析参数失败，使用原始文本");
                parameters["_raw"] = parametersText;
            }

            return parameters;
        }

        private Dictionary<string, object> ParseFunctionParameters(string parametersText)
        {
            var parameters = new Dictionary<string, object>();

            if (string.IsNullOrWhiteSpace(parametersText))
                return parameters;

            // 解析函数参数格式: param1="value1", param2=123, param3=true
            var paramPattern = new Regex(@"(\w+)\s*=\s*([""']?)([^,""']*)\2", RegexOptions.IgnoreCase);
            var matches = paramPattern.Matches(parametersText);

            foreach (Match match in matches)
            {
                var key = match.Groups[1].Value;
                var value = match.Groups[3].Value;

                // 尝试转换类型
                if (bool.TryParse(value, out var boolValue))
                    parameters[key] = boolValue;
                else if (int.TryParse(value, out var intValue))
                    parameters[key] = intValue;
                else if (double.TryParse(value, out var doubleValue))
                    parameters[key] = doubleValue;
                else
                    parameters[key] = value;
            }

            return parameters;
        }

        private EnhancedToolCall? ParseToolCallFromContent(string content)
        {
            // 尝试从内容中解析工具调用
            var lines = content.Split('\n', StringSplitOptions.RemoveEmptyEntries);
            if (lines.Length == 0) return null;

            var firstLine = lines[0].Trim();
            var parts = firstLine.Split(' ', 2);
            if (parts.Length == 0) return null;

            var toolName = parts[0];
            var parametersText = parts.Length > 1 ? parts[1] : "";
            var parameters = ParseParameters(parametersText);

            return new EnhancedToolCall
            {
                ToolName = toolName,
                Parameters = parameters,
                Confidence = 0.8f
            };
        }

        private EnhancedToolCall? InferToolFromAction(string actionDescription)
        {
            // 基于动作描述推断工具调用
            var description = actionDescription.ToLower();

            if (description.Contains("读取") || description.Contains("查看"))
            {
                return new EnhancedToolCall
                {
                    ToolName = "read_file",
                    Parameters = new Dictionary<string, object> { ["description"] = actionDescription },
                    Confidence = 0.7f
                };
            }

            if (description.Contains("搜索") || description.Contains("查找"))
            {
                return new EnhancedToolCall
                {
                    ToolName = "search",
                    Parameters = new Dictionary<string, object> { ["query"] = actionDescription },
                    Confidence = 0.7f
                };
            }

            if (description.Contains("创建") || description.Contains("生成"))
            {
                return new EnhancedToolCall
                {
                    ToolName = "create_content",
                    Parameters = new Dictionary<string, object> { ["description"] = actionDescription },
                    Confidence = 0.6f
                };
            }

            return null;
        }

        private bool IsKnownToolFunction(string functionName)
        {
            // 检查是否是已知的工具函数
            var knownFunctions = new[]
            {
                "read_file", "write_file", "list_files", "search", "create_content",
                "analyze_content", "translate", "summarize", "extract_info"
            };

            return knownFunctions.Contains(functionName.ToLower());
        }

        public ToolCallValidationResult ValidateToolCall(EnhancedToolCall toolCall)
        {
            var result = new ToolCallValidationResult { IsValid = true };

            // 验证工具名称
            if (string.IsNullOrWhiteSpace(toolCall.ToolName))
            {
                result.IsValid = false;
                result.Errors.Add("工具名称不能为空");
            }

            // 验证参数
            if (toolCall.Parameters == null)
            {
                result.IsValid = false;
                result.Errors.Add("参数不能为空");
            }

            // 验证置信度
            if (toolCall.Confidence < 0.5f)
            {
                result.Warnings.Add("工具调用置信度较低，可能解析不准确");
            }

            return result;
        }

        public string FormatToolCallResult(EnhancedToolCall toolCall, object result)
        {
            try
            {
                var resultText = result?.ToString() ?? "无结果";
                
                return toolCall.Format switch
                {
                    ToolCallFormat.TextBased => $"[RESULT:{toolCall.ToolName}]{resultText}[/RESULT]",
                    ToolCallFormat.JsonBased => JsonSerializer.Serialize(new { tool = toolCall.ToolName, result = resultText }),
                    ToolCallFormat.MarkdownBased => $"```result\n{toolCall.ToolName}: {resultText}\n```",
                    ToolCallFormat.XMLBased => $"<result tool=\"{toolCall.ToolName}\">{resultText}</result>",
                    _ => $"✅ {toolCall.ToolName}: {resultText}"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "格式化工具调用结果失败");
                return $"❌ 格式化结果失败: {ex.Message}";
            }
        }
    }

    /// <summary>
    /// 增强的工具调用
    /// </summary>
    public class EnhancedToolCall
    {
        public string ToolName { get; set; } = string.Empty;
        public Dictionary<string, object> Parameters { get; set; } = new();
        public ToolCallFormat Format { get; set; }
        public string OriginalText { get; set; } = string.Empty;
        public int Position { get; set; }
        public float Confidence { get; set; } = 1.0f;
        public DateTime Timestamp { get; set; } = DateTime.Now;
        public string? Context { get; set; }
        public Dictionary<string, object> Metadata { get; set; } = new();
    }

    /// <summary>
    /// 工具调用格式
    /// </summary>
    public enum ToolCallFormat
    {
        NativeFunction,  // function_name(param1="value1")
        TextBased,       // [TOOL:name]params[/TOOL]
        ActionBased,     // [ACTION:description]
        JsonBased,       // ```json {"tool": "name", "parameters": {...}} ```
        MarkdownBased,   // ```tool name params ```
        XMLBased         // <tool name="name" args="params"/>
    }

    /// <summary>
    /// 工具调用验证结果
    /// </summary>
    public class ToolCallValidationResult
    {
        public bool IsValid { get; set; }
        public List<string> Errors { get; set; } = new();
        public List<string> Warnings { get; set; } = new();
    }
}
